using System;
using System.Windows.Forms;

namespace Shrapnel.Interaction
{
    /// <summary>
    /// The base class for all kind of interaction styles.
    /// </summary>
    public abstract class Style
    {
		//
		// Latent actions:
		//

		/// <summary>
		/// Determine if we should start panning, given the provided buttons and keys.
		/// </summary>
		/// <param name="mouseButtons">Current state of the mousebuttons</param>
		/// <param name="modifierKeys">Current state of additional modifier keys</param>
		/// <param name="above">Indicates above which node our mousecursor was</param>
		/// <returns></returns>
		public abstract bool ShouldStartPanning(MouseButtons mouseButtons, Keys modifierKeys, AboveElementType above);

		/// <summary>
		/// Determine if we should stop panning, given the provided buttons and keys.
		/// </summary>
		/// <param name="mouseButtons">Current state of the mousebuttons</param>
		/// <param name="modifierKeys">Current state of additional modifier keys</param>
		/// <returns></returns>
		public abstract bool ShouldStopPanning(MouseButtons mouseButtons, Keys modifierKeys);

		/// <summary>
		/// Determine if we should start (area)selecting, given the provided buttons and keys.
		/// </summary>
		/// <param name="mouseButtons">Current state of the mousebuttons</param>
		/// <param name="modifierKeys">Current state of additional modifier keys</param>
		/// <param name="above">Indicates above which node our mousecursor was</param>
		/// <returns></returns>
		public abstract bool ShouldStartSelecting(MouseButtons mouseButtons, Keys modifierKeys, AboveElementType above);

		/// <summary>
		/// Determine if we should stop selecting, given the provided buttons and keys.
		/// </summary>
		/// <param name="mouseButtons">Current state of the mousebuttons</param>
		/// <param name="modifierKeys">Current state of additional modifier keys</param>
		/// <returns></returns>
		public abstract bool ShouldStopSelecting(MouseButtons mouseButtons, Keys modifierKeys);

		/// <summary>
		/// Determine if we should start zooming, given the provided buttons and keys.
		/// </summary>
		/// <param name="mouseButtons">Current state of the mousebuttons</param>
		/// <param name="modifierKeys">Current state of additional modifier keys</param>
		/// <param name="above">Indicates above which node our mousecursor was</param>
		/// <returns></returns>
		public abstract bool ShouldStartZooming(MouseButtons mouseButtons, Keys modifierKeys, AboveElementType above);

		/// <summary>
		/// Determine if we should stop zooming, given the provided buttons and keys.
		/// </summary>
		/// <param name="mouseButtons">Current state of the mousebuttons</param>
		/// <param name="modifierKeys">Current state of additional modifier keys</param>
		/// <returns></returns>
		public abstract bool ShouldStopZooming(MouseButtons mouseButtons, Keys modifierKeys);

		/// <summary>
		/// Determine if we should start moving, given the provided buttons and keys.
		/// </summary>
		/// <param name="mouseButtons">Current state of the mousebuttons</param>
		/// <param name="modifierKeys">Current state of additional modifier keys</param>
		/// <param name="above">Indicates above which node our mousecursor was</param>
		/// <returns></returns>
		public abstract bool ShouldStartMoving(MouseButtons mouseButtons, Keys modifierKeys, AboveElementType above);

		/// <summary>
		/// Determine if we should stop moving, given the provided buttons and keys.
		/// </summary>
		/// <param name="mouseButtons">Current state of the mousebuttons</param>
		/// <param name="modifierKeys">Current state of additional modifier keys</param>
		/// <returns></returns>
		public abstract bool ShouldStopMoving(MouseButtons mouseButtons, Keys modifierKeys);

		/// <summary>
		/// Determine if we should start wiring, given the provided buttons and keys.
		/// </summary>
		/// <param name="mouseButtons">Current state of the mousebuttons</param>
		/// <param name="modifierKeys">Current state of additional modifier keys</param>
		/// <param name="above">Indicates above which node our mousecursor was</param>
		/// <returns></returns>
		public abstract bool ShouldStartWiring(MouseButtons mouseButtons, Keys modifierKeys, AboveElementType above);

		/// <summary>
		/// Determine if we should stop wiring, given the provided buttons and keys.
		/// </summary>
		/// <param name="mouseButtons">Current state of the mousebuttons</param>
		/// <param name="modifierKeys">Current state of additional modifier keys</param>
		/// <returns></returns>
		public abstract bool ShouldStopWiring(MouseButtons mouseButtons, Keys modifierKeys);



		//
		// Instant actions:
		//


		/// <summary>
		/// Determine if we should fit the selection in our view, given the provided keys.
		/// </summary>
		/// <param name="keyArgs">Pressed key(s)</param>
		/// <param name="modifierKeys">Additional modifierkeys that are active</param>
		/// <returns></returns>
		public abstract bool ShouldDoFitSelectionInView(KeyEventArgs keyArgs, Keys modifierKeys);

		/// <summary>
		/// Determine if we should fit all nodes in our view, given the provided keys.
		/// </summary>
		/// <param name="keyArgs">Pressed key(s)</param>
		/// <param name="modifierKeys">Additional modifierkeys that are active</param>
		/// <returns></returns>
		public abstract bool ShouldDoFitAllInView(KeyEventArgs keyArgs, Keys modifierKeys);

		/// <summary>
		/// Determine if we should delete all selected nodes, given the provided keys.
		/// </summary>
		/// <param name="keyArgs">Pressed key(s)</param>
		/// <param name="modifierKeys">Additional modifierkeys that are active</param>
		/// <returns></returns>
		public abstract bool ShouldDoDeleteSelection(KeyEventArgs keyArgs, Keys modifierKeys);

		/// <summary>
		/// Determine if we should select all elements, given the provided keys.
		/// </summary>
		/// <param name="keyArgs">Pressed key(s)</param>
		/// <param name="modifierKeys">Additional modifierkeys that are active</param>
		/// <returns></returns>
		public abstract bool ShouldDoSelectAll(KeyEventArgs keyArgs, Keys modifierKeys);

		/// <summary>
		/// Determine if we should deselect all elements, given the provided keys.
		/// </summary>
		/// <param name="keyArgs">Pressed key(s)</param>
		/// <param name="modifierKeys">Additional modifierkeys that are active</param>
		/// <returns></returns>
		public abstract bool ShouldDoDeselectAll(KeyEventArgs keyArgs, Keys modifierKeys);

		/// <summary>
		/// Determine if we should copy our selection, given the provided keys.
		/// </summary>
		/// <param name="keyArgs">Pressed key(s)</param>
		/// <param name="modifierKeys">Additional modifierkeys that are active</param>
		/// <returns></returns>
		public abstract bool ShouldDoCopySelection(KeyEventArgs keyArgs, Keys modifierKeys);

		/// <summary>
		/// Determine if we should cut our selection, given the provided keys.
		/// </summary>
		/// <param name="keyArgs">Pressed key(s)</param>
		/// <param name="modifierKeys">Additional modifierkeys that are active</param>
		/// <returns></returns>
		public abstract bool ShouldDoCutSelection(KeyEventArgs keyArgs, Keys modifierKeys);

		/// <summary>
		/// Determine if we should paste, given the provided keys.
		/// </summary>
		/// <param name="keyArgs">Pressed key(s)</param>
		/// <param name="modifierKeys">Additional modifierkeys that are active</param>
		/// <returns></returns>
		public abstract bool ShouldDoPaste(KeyEventArgs keyArgs, Keys modifierKeys);

        /// <summary>
        /// Determine if we should print the workspace, given the provided keys.
        /// </summary>
        /// <param name="keyArgs">Pressed key(s)</param>
        /// <param name="modifierKeys">Additional modifierkeys that are active</param>
        /// <returns></returns>
        public abstract bool ShouldPrint(KeyEventArgs keyArgs, Keys modifierKeys);
    }
}
